package com.sys.server.common.annotation.interceptor;

import com.sys.server.common.annotation.Authentication;
import com.sys.server.common.constants.CommonConstant;
import com.sys.server.common.utils.HttpServletUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 自定义拦截器，用户登录校验
 *
 * @author shanbingzhen
 * @date 2022-01-10 20:24
 */
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return hasPermission(request, response, handler);
    }

    private boolean hasPermission(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Authentication authentication = handlerMethod.getMethod().getDeclaringClass().getDeclaredAnnotation(Authentication.class);
            if (authentication == null) {
                return true;
            } else {
                String token = HttpServletUtil.getRequestHeader(CommonConstant.Authentication);
                if (token != null && Boolean.TRUE.equals(redisTemplate.hasKey(token))) {
                    redisTemplate.expire(token, 60*60*3, TimeUnit.SECONDS);
                    return true;
                } else {
                    // 如果token校验失败，返回状态码为403
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    return false;
                }
            }
        }
        return true;
    }

}
